package com.springboot.spring01ioc;

import com.springboot.spring01ioc.bean.Car;
import com.springboot.spring01ioc.bean.Dog;
import com.springboot.spring01ioc.bean.Person;
import com.springboot.spring01ioc.bean.User;
import com.springboot.spring01ioc.controller.UserController;
import com.springboot.spring01ioc.dao.DeliveryDao;
import com.springboot.spring01ioc.dao.UserDao;
import com.springboot.spring01ioc.service.EnvironmentService;
import com.springboot.spring01ioc.service.UserService;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.Environment;
import org.springframework.util.ResourceUtils;


import javax.xml.transform.Source;
import java.util.Map;

//主入口类，为主程序类

@SpringBootApplication
public class Spring01IocApplication {

    public static void main(String[] args) {
        //查看Bean完整的生命周期

        ConfigurableApplicationContext ioc = SpringApplication.run(Spring01IocApplication.class, args);
        System.out.println("==========ioc容器创建完成==========");

        User user = ioc.getBean(User.class);
        System.out.println("运行：" + user);

    }


    public static void text12(String[] args) {
        //查看哪个数据源生效
        ConfigurableApplicationContext ioc = SpringApplication.run(Spring01IocApplication.class, args);
        System.out.println("==========ioc容器创建完成==========");

        DeliveryDao dao = ioc.getBean(DeliveryDao.class);
        System.out.println("dao = " + dao);

        dao.saveDelivery();

    }


    public static void text11(String[] args) {
        //Value给属性赋值,并使用PropertySource向dog中引入文件配置

        /*也可以使用ResourceUtils来获取资源
        ResourceUtils.getFile("classpath = ");
        */

        ConfigurableApplicationContext ioc = SpringApplication.run(Spring01IocApplication.class, args);
        System.out.println("==========ioc容器创建完成==========");

        Dog dog = ioc.getBean(Dog.class);
        System.out.println("Dog = " + dog);


    }

    public static void text10(String[] args) {
        //感知注入
        ConfigurableApplicationContext ioc = SpringApplication.run(Spring01IocApplication.class, args);
        System.out.println("==========ioc容器创建完成==========");
        EnvironmentService environmentService = ioc.getBean(EnvironmentService.class);
        System.out.println("EnvironmentService = "  +  environmentService );

    }


    public static void text09(String[] args) {
        //setter方法注入
        ConfigurableApplicationContext ioc = SpringApplication.run(Spring01IocApplication.class, args);
        System.out.println("==========ioc容器创建完成==========");
        UserDao dao = ioc.getBean(UserDao.class);
        System.out.println("dao = " + dao);
    }

    public static void text08(String[] args) {
        //构造器注入
        ConfigurableApplicationContext ioc = SpringApplication.run(Spring01IocApplication.class, args);
        System.out.println("==========ioc容器创建完成==========");
        UserDao dao = ioc.getBean(UserDao.class);
        System.out.println("dao = " + dao);
    }

    public static void test07(String[] args) {
        //自动注入： Autowired 和 Resourse
        ConfigurableApplicationContext ioc = SpringApplication.run(Spring01IocApplication.class, args);
        System.out.println("==========ioc容器创建完成==========");
        UserService service = ioc.getBean(UserService.class);
        System.out.println("servic = " + service);
    }


    public static void text06(String[] args) {
        ConfigurableApplicationContext ioc = SpringApplication.run(Spring01IocApplication.class, args);
        System.out.println("==========ioc容器创建完成==========");
        //使用Autowired直接注入
        UserController bean = ioc.getBean(UserController.class);
        System.out.println("bean = " + bean);
    }

    public static void text05(String[] args) {
        ConfigurableApplicationContext ioc = SpringApplication.run(Spring01IocApplication.class, args);

        Map<String, Person> beansOfType = ioc.getBeansOfType(Person.class);
        System.out.println("bean = " + beansOfType);

        //拿到环境变量
        ConfigurableEnvironment environment = ioc.getEnvironment();

        String property = environment.getProperty("OS");
        System.out.println("property = " + property);

    }



    public static void text04(String[] args) {
        ConfigurableApplicationContext ioc = SpringApplication.run(Spring01IocApplication.class, args);
        System.out.println("==========ioc容器创建完成==========");

        Car bean1 = ioc.getBean(Car.class);
        Car bean2 = ioc.getBean(Car.class);
        System.out.println(bean1 == bean2);
        //FactoryBean在容器中存放的组件类型，是接口指定泛式的类型，组件名字则是工厂自己名字
        Map<String, Car> type = ioc.getBeansOfType(Car.class);
        System.out.println("type = " + type);
    }

    /*
    默认：分层注解起作用前提是：这些程序必须在主程序的包以及其所在子包下
    @Componentscan：组件批量扫描（只扫有Spring相关注解）
    Spring提供了快速的MVC分层注解（都是Component组件）
    1.控制器 @Controller
    2.服务层 @Service
    3.持久层 @Repository
    4.组件 @Component
    */


    public static void test03(String[] args) {
        ConfigurableApplicationContext ioc = SpringApplication.run(Spring01IocApplication.class, args);

        System.out.println("=============");

        UserController bean = ioc.getBean(UserController.class);

        System.out.println("bean = " + bean);
    }

    public static void test02(String[] args) {
        //1。跑起一个Spring应用：ApplicationContext

        ConfigurableApplicationContext ioc = SpringApplication.run(Spring01IocApplication.class, args);
        System.out.println("ioc="+ioc);
        System.out.println("=========================");
        //2.容器中有哪些组件:获取容器中所有组件名字(默认组件)
        String[] names = ioc.getBeanDefinitionNames();
        for (String name : names) {
            System.out.println("name=" + name);
        }

        /*4.获取容器中组件对象
       （组件四大特性：名字、类型、对象、作用域）
       */
        //4.1 按照组件名字获取对象
        Object zhangsan = ioc.getBean("zhangsan1");
        System.out.println("对象=" + zhangsan);
        /*4.2 按照组件类型获取对象
        Person bean = ioc.getBean(Person.class);
        System.out.println("对象=" + bean);
        */
        //4.3 按照组件类型获取所有对象
        Map<String, Person> beansOfType = ioc.getBeansOfType(Person.class);
        System.out.println("Type=" + beansOfType);
        //4,4 按照类型+名字
        Person bean2 = ioc.getBean("zhangsan2", Person.class);
        System.out.println("bean2=" + bean2);

    }


        //5 组件是单实例，所有组件默认为单例，每次获取直接从容器拿（重复获取到的组件均相同）
        //注：创建时机：容器启动过程中就会创建组件


/*小结：1.容器无该组件：抛出异常
       2.组件不唯一：按照类型只返回一个抛出异常；
                   按照名字只返回一个：精确获取
                   返回多个则正常返回包含所有组件的List集合；
       3.组件唯一：精确返回
       4.组件名重复：把先创建放入容器
       */

//   3.项目中注册一个自己的组件


    //声明默认配置类

}
